<!DOCTYPE html>
<html lang="en-us" dir="ltr">
    <head><meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'><meta name='description' content="文件系统访问块设备数据时存在访问粒度不一致的问题，会引起双份拷贝和写放大等问题，争对该问题文件系统有一些优化，比如使用读缓存和写缓冲区及写合并。内存映射就是跳过页缓存，将磁盘文件映射到内存上，直接对内存执行load/store等操作。">
<title>页缓存、直接IO及内存映射</title>

<link rel='canonical' href='http://36.41.71.150/post/page_cache/'>

<link rel="stylesheet" href="/scss/style.min.663803bebe609202d5b39d848f2d7c2dc8b598a2d879efa079fa88893d29c49c.css"><meta property='og:title' content="页缓存、直接IO及内存映射">
<meta property='og:description' content="文件系统访问块设备数据时存在访问粒度不一致的问题，会引起双份拷贝和写放大等问题，争对该问题文件系统有一些优化，比如使用读缓存和写缓冲区及写合并。内存映射就是跳过页缓存，将磁盘文件映射到内存上，直接对内存执行load/store等操作。">
<meta property='og:url' content='http://36.41.71.150/post/page_cache/'>
<meta property='og:site_name' content='ydsungan 的博客'>
<meta property='og:type' content='article'><meta property='article:section' content='Post' /><meta property='article:tag' content='操作系统' /><meta property='article:published_time' content='2022-03-30T14:30:12&#43;08:00'/><meta property='article:modified_time' content='2022-03-30T14:30:12&#43;08:00'/>
<meta name="twitter:title" content="页缓存、直接IO及内存映射">
<meta name="twitter:description" content="文件系统访问块设备数据时存在访问粒度不一致的问题，会引起双份拷贝和写放大等问题，争对该问题文件系统有一些优化，比如使用读缓存和写缓冲区及写合并。内存映射就是跳过页缓存，将磁盘文件映射到内存上，直接对内存执行load/store等操作。">
    </head>
    <body class="
    article-page
    ">
    <script>
        (function() {
            const colorSchemeKey = 'StackColorScheme';
            if(!localStorage.getItem(colorSchemeKey)){
                localStorage.setItem(colorSchemeKey, "auto");
            }
        })();
    </script><script>
    (function() {
        const colorSchemeKey = 'StackColorScheme';
        const colorSchemeItem = localStorage.getItem(colorSchemeKey);
        const supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true;

        if (colorSchemeItem == 'dark' || colorSchemeItem === 'auto' && supportDarkMode) {
            

            document.documentElement.dataset.scheme = 'dark';
        } else {
            document.documentElement.dataset.scheme = 'light';
        }
    })();
</script>
<div class="container main-container flex on-phone--column extended"><aside class="sidebar left-sidebar sticky ">
    <button class="hamburger hamburger--spin" type="button" id="toggle-menu" aria-label="Toggle Menu">
        <span class="hamburger-box">
            <span class="hamburger-inner"></span>
        </span>
    </button>

    <header>
        
            
            <figure class="site-avatar">
                <a href="/">
                
                    
                    
                    
                        
                        <img src="/img/avatar_hu10196295592476096514.jpg" width="300"
                            height="300" class="site-logo" loading="lazy" alt="Avatar">
                    
                
                </a>
                
                    <span class="emoji">🍥</span>
                
            </figure>
            
        
        
        <div class="site-meta">
            <h1 class="site-name"><a href="/">ydsungan 的博客</a></h1>
            <h2 class="site-description">任凭风浪起，稳坐钓鱼台</h2>
        </div>
    </header><ol class="menu-social">
            
                <li>
                    <a 
                        href='https://gitee.com/ydsungan'
                        target="_blank"
                        title="GitHub"
                        rel="me"
                    >
                        
                        
                            <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-github" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
  <path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" />
</svg>



                        
                    </a>
                </li>
            
                <li>
                    <a 
                        href='https://twitter.com'
                        target="_blank"
                        title="Twitter"
                        rel="me"
                    >
                        
                        
                            <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-twitter" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
  <path d="M22 4.01c-1 .49 -1.98 .689 -3 .99c-1.121 -1.265 -2.783 -1.335 -4.38 -.737s-2.643 2.06 -2.62 3.737v1c-3.245 .083 -6.135 -1.395 -8 -4c0 0 -4.182 7.433 4 11c-1.872 1.247 -3.739 2.088 -6 2c3.308 1.803 6.913 2.423 10.034 1.517c3.58 -1.04 6.522 -3.723 7.651 -7.742a13.84 13.84 0 0 0 .497 -3.753c-.002 -.249 1.51 -2.772 1.818 -4.013z" />
</svg>



                        
                    </a>
                </li>
            
                <li>
                    <a 
                        href='https://weibo.com/u/7203149652'
                        target="_blank"
                        title="Weibo"
                        rel="me"
                    >
                        
                        
                            <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1728725633554" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4295" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M507.722667 393.525333c3.018667-0.202667 5.685333-0.618667 7.594666-1.141333 15.626667-12.458667 47.68-28.864 76.8-37.802667 48-14.72 90.24-12.16 118.421334 18.688 8.490667 9.301333 14.346667 19.562667 17.386666 30.698667 6.314667 23.04 2.453333 37.184-11.754666 69.248-10.506667 23.722667-11.146667 29.888-3.808 39.530667 4.896 6.410667 10.432 8.917333 22.293333 10.24 3.157333 0.362667 5.749333 0.554667 12.373333 0.96 57.472 3.605333 84.970667 26.922667 84.970667 98.538666 0 86.901333-60.821333 158.005333-160.138667 208.64C592.554667 871.530667 491.818667 896 415.072 896c-90.773333 0-175.872-18.026667-237.312-59.882667C93.546667 778.752 63.68 683.445333 101.514667 553.536c30.154667-103.541333 158.357333-246.88 279.114666-298.4 27.082667-11.562667 61.685333-13.962667 86.709334-1.706667 38.378667 18.773333 44.693333 61.184 20.128 111.946667-9.525333 19.68-8.576 22.368-0.426667 25.525333 5.514667 2.133333 13.226667 3.104 20.682667 2.624z m-77.866667-56.021333c6.293333-13.013333 8.597333-22.101333 8.341333-27.018667-6.613333-2.368-21.568-1.130667-32.458666 3.52C302.528 358.026667 187.733333 486.4 162.965333 571.424c-30.368 104.245333-9.557333 170.656 50.826667 211.786667C262.56 816.448 335.978667 832 415.072 832c66.592 0 157.365333-22.048 227.722667-57.898667C722.944 733.248 768 680.565333 768 622.485333c0-12.224-1.12-21.141333-2.986667-27.029333-1.002667-3.168-1.76-4.373333-2.24-4.768-1.226667-1.056-5.418667-1.962667-19.744-2.858667a283.594667 283.594667 0 0 1-15.498666-1.237333c-27.701333-3.093333-49.088-12.768-66.069334-35.061333-25.749333-33.781333-22.901333-61.141333-3.808-104.234667 7.904-17.856 9.397333-23.317333 8.544-26.432-0.277333-1.034667-1.056-2.4-2.912-4.426667-7.125333-7.797333-25.525333-8.917333-52.384-0.672-12.373333 3.797333-25.301333 9.258667-37.130666 15.445334-9.12 4.768-16.714667 9.578667-18.837334 11.445333-19.178667 16.821333-60.981333 19.541333-90.986666 7.936-44.064-17.056-59.456-60.672-34.08-113.088z m505.834667 85.610667a32 32 0 1 1-63.253334-9.706667C873.92 403.733333 874.666667 393.92 874.666667 384c0-106.037333-85.962667-192-192-192-2.794667 0-5.578667 0.064-8.352 0.181333a32 32 0 1 1-2.730667-63.946666c3.690667-0.16 7.381333-0.234667 11.082667-0.234667 141.386667 0 256 114.613333 256 256 0 13.173333-1.002667 26.24-2.976 39.114667z m-104.288-14.976a32 32 0 1 1-63.744-5.717334A85.333333 85.333333 0 0 0 682.666667 309.333333a32 32 0 0 1 0-64c82.474667 0 149.333333 66.858667 149.333333 149.333334 0 4.512-0.202667 9.013333-0.597333 13.472z" fill="#515151" p-id="4296"></path></svg>
                        
                    </a>
                </li>
            
        </ol><ol class="menu" id="main-menu">
        
        
        
        <li >
            <a href='/archives/' >
                
                
                
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-archive" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <rect x="3" y="4" width="18" height="4" rx="2" />
  <path d="M5 8v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-10" />
  <line x1="10" y1="12" x2="14" y2="12" />
</svg>



                
                <span>Archives</span>
            </a>
        </li>
        
        
        <li >
            <a href='/search/' >
                
                
                
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-search" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="10" cy="10" r="7" />
  <line x1="21" y1="21" x2="15" y2="15" />
</svg>



                
                <span>Search</span>
            </a>
        </li>
        
        
        <li >
            <a href='/about' >
                
                
                
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-user" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="12" cy="7" r="4" />
  <path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2" />
</svg>



                
                <span>About</span>
            </a>
        </li>
        
        <li class="menu-bottom-section">
            <ol class="menu">

                
                    <li id="dark-mode-toggle">
                        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="8" cy="12" r="2" />
  <rect x="2" y="6" width="20" height="12" rx="6" />
</svg>



                        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="16" cy="12" r="2" />
  <rect x="2" y="6" width="20" height="12" rx="6" />
</svg>



                        <span>Dark Mode</span>
                    </li>
                
            </ol>
        </li>
    </ol>
</aside>

    <aside class="sidebar right-sidebar sticky">
        
            
                
    <section class="widget archives">
        <div class="widget-icon">
            <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-hash" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <line x1="5" y1="9" x2="19" y2="9" />
  <line x1="5" y1="15" x2="19" y2="15" />
  <line x1="11" y1="4" x2="7" y2="20" />
  <line x1="17" y1="4" x2="13" y2="20" />
</svg>



        </div>
        <h2 class="widget-title section-title">Table of contents</h2>
        
        <div class="widget--toc">
            <nav id="TableOfContents">
  <ul>
    <li><a href="#1-访问粒度不一致问题和一些优化">1 访问粒度不一致问题和一些优化</a></li>
    <li><a href="#2-读缓存">2 读缓存</a></li>
    <li><a href="#3-写缓冲区和写合并">3 写缓冲区和写合并</a></li>
    <li><a href="#4-页缓存">4 页缓存</a></li>
    <li><a href="#5-直接io">5 直接IO</a></li>
    <li><a href="#6-内存映射">6 内存映射</a></li>
    <li><a href="#7-页缓存与内存映射的区别">7 页缓存与内存映射的区别</a></li>
  </ul>
</nav>
        </div>
    </section>

            
        
            
                <section class="widget tagCloud">
    <div class="widget-icon">
        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-tag" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <path d="M11 3L20 12a1.5 1.5 0 0 1 0 2L14 20a1.5 1.5 0 0 1 -2 0L3 11v-4a4 4 0 0 1 4 -4h4" />
  <circle cx="9" cy="9" r="2" />
</svg>



    </div>
    <h2 class="widget-title section-title">Tags</h2>

    <div class="tagCloud-tags">
        
            <a href="/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/" class="font_size_2">
                操作系统
            </a>
        
            <a href="/tags/intel/" class="font_size_1">
                intel
            </a>
        
            <a href="/tags/%E8%BD%AF%E4%BB%B6/" class="font_size_1">
                软件
            </a>
        
    </div>
</section>
            
        
    </aside>


            <main class="main full-width">
    <article class="main-article">
    <header class="article-header">

    <div class="article-details">
    
    <header class="article-category">
        
            <a href="/categories/linux/" >
                Linux
            </a>
        
    </header>
    

    <div class="article-title-wrapper">
        <h2 class="article-title">
            <a href="/post/page_cache/">页缓存、直接IO及内存映射</a>
        </h2>
    
        
        <h3 class="article-subtitle">
            文件系统访问块设备数据时存在访问粒度不一致的问题，会引起双份拷贝和写放大等问题，争对该问题文件系统有一些优化，比如使用读缓存和写缓冲区及写合并。内存映射就是跳过页缓存，将磁盘文件映射到内存上，直接对内存执行load/store等操作。
        </h3>
        
    </div>

    
    
    
    
    <footer class="article-time">
        
            <div>
                <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-calendar-time" width="56" height="56" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <path d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4" />
  <circle cx="18" cy="18" r="4" />
  <path d="M15 3v4" />
  <path d="M7 3v4" />
  <path d="M3 11h16" />
  <path d="M18 16.496v1.504l1 1" />
</svg>
                <time class="article-time--published">2022 年 3 月 30 日</time>
            </div>
        

        
            <div>
                <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="12" cy="12" r="9" />
  <polyline points="12 7 12 12 15 15" />
</svg>



                <time class="article-time--reading">
                    1 minute read
                </time>
            </div>
        
    </footer>
    

    
</div>

</header>

    <section class="article-content">
    
    
    <p>​		对文件系统中结构的修改都是直接在存储设备中进行的。然而在存储设备上直接访问数据有两个问题。首先，目前大多数存储设备都是块接口，读写粒度为—个块，大小通常为 512B 或者 4KB。然而文件系统所进行的更改往往并非对齐到块的边界，其读写的字节数也并非恰好为块大小的整数倍。其次，存储设备的访问速度慢，与内存相比要慢几个数量级。大量频繁的存储设备访问操作会成为应用程序的性能瓶颈。</p>
<h2 id="1-访问粒度不一致问题和一些优化">1 访问粒度不一致问题和一些优化
</h2><p>​		文件系统使用内存作为中转来解决访问粒度不—致的问题。假设一个存储设备的块大小为 4KB。当文件系统需要修改存储设备中的 8B 时，其需要先从存储设备中找到这8个字节所在的块号。通过块号，文件系统将整个块中的数据读入一个 4KB 大小的内存页之中。文件系统在内存页中修改这8个字节，并将修改后的内存页通过驱动写回到存储设备之中。这实际上是一个“读取—修改—写回”的过程。</p>
<p>​		其中一个明显的问题是，若每个文件请求中每个结构的修改都经过完整的 “<strong>读取-修改-写回</strong>” 过程，将会产生大量的磁盘访问。有一些比较简单的优化可以避免一些不必要的磁盘访问。</p>
<p>​		之所以要在修改和写回之前先读取，是因为我们只想修改存储块下的一部分，而写回操作会覆盖整个存储块。为了保证此存储块中其他部分的数据不变，我们需要先将这些数据读出来，之后随修改后的数据一同写回到存储设备中。但是，如果一次修改的数据量刚好覆盖了整个存储块，那么就不用进行读取操作，可以直接将修改后的4096个字节写回到存储设备中。</p>
<p>​		此外，如果一个文件请求中的多次修改均是在同—个存储块中，那么可以将多次修改合并到一个 “<strong>读取-修改-写回</strong>” 的过程中，即变为 “<strong>读取-修改1-修改2-修改3-…修改n-写回</strong>” 。这样，同样访问了两次存储设备，却完成了多次修改。</p>
<h2 id="2-读缓存">2 读缓存
</h2><p>​		文件的访问具有时间局部性：当文件的一部分被访问后，有较高的概率其会再次被使用。因此，当文件系统从设备中读取了某个文件的数据之后，可以让这些数据继续保留在内存中一段时间。这样，当应用程序需要再次读取这些数据时，就可以从此前保留在内存中的数据中读取，从而避免了存储设备的访问。这便是文件系统中的读缓存。</p>
<p>​		读缓存是需要占用内存空间的。为了防止该缓存占用过多的内存，澡作系统会对读缓存的大小进行限制。当读缓存占用过多内存时，使用 LRU 等策略回收读缓存占用的内存。</p>
<h2 id="3-写缓冲区和写合并">3 写缓冲区和写合并
</h2><p>​		一般默认一个写请求结束之后，所有的写入数据均已被持久化到存储设备上，也就是说在文件写入请求完成后立刻发生断电和崩溃等情况，在系统恢复后，刚刚写入的文件数据依然能够被读取到。这是一个较强但十分合理的保证。然而由于存储设备的性能较差，若每个写请求均等待写入设备完成，文件写操作的延时变长，吞吐量会严重下降，从而影响整个系统的性能。</p>
<p>​		为了获得更好的性能，在文件系统的设计中有一个权衡：在—个文件写请求返回到应用程序之后，允许其修改的数据暂时不持久化到存储设备中。这个权衡允许文件系统暂时将修改的数据保存在内存中，并在后台慢慢地持久化到存储设备上，然而这样却牺牲了—定的可靠性。在前面的例子中，如果在文件写请求完成后立刻发生断电，再次开机之后，刚刚完成写入的数据可能会丢失。为了确保数据被持久化到设备中，POSIX 中规定了 <strong>fsync</strong> 接口，用于保证某个已打开文件的所有修改全部被持久化到存储设备中。</p>
<p>​		当文件系统修改完文件数据后，其修改会被暂存在写缓冲区的内存页之中。如果后续的文件请求需要读取或者修改相同存储块中的数据，文件系统可以直接在写缓冲区对应的内存页上进行读取或者修改。当可用内存不足，或者对应的 <strong>fsync</strong> 被调用时，写缓冲区内存页中的数据才写回到存储设备对应的存储块之中。这样，一段时间内同一个存储块上的多个写请求可以合并一个磁盘写操作。</p>
<h2 id="4-页缓存">4 页缓存
</h2><p>​		在Linux内核中，读缓存与写缓冲区的功能被合并起来管理，称为页缓存。页缓存以内存页为单位，将存储设备中的存储位置映射到内存中。文件系统通过调用 VFS 提供的相应接口对页缓存进行操作。</p>
<p>​		当—个文件被读取时，文件系统会先检查其内容是否已经保存在页缓存中。如果文件数据已保存在页缓存中，则文件系统直接从页缓存中读取数据返回给应用程序；否则，文件系统会在页缓存中创建新的内存页，并从存储设备中读取相关的数据然后将其保存在创建的内存页中。之后，文件系统从内存页中读取相应的数据，返回给应用程序。</p>
<p>​		在进行文件修改时，文件系统同样会首先检查页缓存。如果要修改的数据已经在页缓存中，文件系统可以直接修改页缓存中的数据，并将该页标记为脏页；若不在页缓存中，文件系统同样先创建页缓存并从存储没备中读取数据，然后在页缓存中进行修改并标记该页为脏页。标记为脏页的缓存会由文件系统定期写回到存储设备中。当操作系统内存不足或者应用程序调用 <strong>fsync</strong> 时，文件系统也会将脏页中的数据写回到存储设备中。</p>
<h2 id="5-直接io">5 直接IO
</h2><p>​		<strong>直接IO</strong>就是不需要读缓冲，不需要写缓冲区和写合并。</p>
<p>​		页缓存是持久化和性能之间权衡的产物。在大多数情况下，页缓存能够显著地提升文件系统性能。然而并非在所有情况下页缓存都能起到正面作用。一方面，部分应用对数据持久化有较强的要求，不希望文件的修改内容缓存在页缓存中。如果使用页缓存的机制，这些应用需要在每次修改文件后立即执行 <strong>fsync</strong> 操作进行同步，这会影响应用程序的性能。另一方面，一些应用程序（如数据库等）会自己实现缓存机制对数据进行缓存和管理。由于应用程序更加了解自己对数据的需求,在这种情况下，操作系统提供的页缓存机制是冗余的，且一般会带来额外的性能开销。</p>
<p>​		因此，文件系统将是否使用页缓存的判断和选择权交给了应用程序。应用程序可以在打开文件时通过附带 <strong>O_DIRECT</strong> 标志，提示文件系统不要使用页缓存。这种文件访问方式就是<strong>直接 I/O</strong> 。而相对应地，使用页缓存的文件请求称为缓存I/O。</p>
<h2 id="6-内存映射">6 内存映射
</h2><p>​		除了文件的 read 和 write 接口外，应用程序还可以通过内存映射机制，以访问内存的形式访问文件内容。Linux在其页缓存的基础上实现了文件的内存映射机制。</p>
<p>​		将一个文件或者其它对象映射到进程虚拟地址空间，实现文件磁盘地址和进程虚拟地址空间中的地址一一对映关系。</p>
<p>​		<img src="/post/mmap_1.png"
	
	
	
	loading="lazy"
	
		alt="内存映射"
	
	
></p>
<h2 id="7-页缓存与内存映射的区别">7 页缓存与内存映射的区别
</h2><ol>
<li>页缓存IO中数据从块设备到页缓存，再到用户缓冲区，经过俩次拷贝；而 mmap 方式下，当发生缺页中断时才去磁盘拷贝，然后直接对内存读写。</li>
<li>处理大文件时，页缓存IO方式使用 read/write 系统调用一块一块的双份拷贝，而 mmap 方式把文件映射到虚拟地址空间，可以让磁盘空间替代内存。</li>
</ol>

</section>


    <footer class="article-footer">
    
    <section class="article-tags">
        
            <a href="/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/">操作系统</a>
        
    </section>


    </footer>


    
        <link 
                rel="stylesheet" 
                href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css"integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI&#43;WdtXRGWt2kTvGFasHpSy3SV"crossorigin="anonymous"
            ><script 
                src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"integrity="sha384-XjKyOOlGwcjNTAIQHIpgOno0Hl1YQqzUOEleOLALmuqehneUG&#43;vnGctmUb0ZY0l8"crossorigin="anonymous"
                defer
                >
            </script><script 
                src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"integrity="sha384-&#43;VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4&#43;/RRE05"crossorigin="anonymous"
                defer
                >
            </script><script>
    window.addEventListener("DOMContentLoaded", () => {
        renderMathInElement(document.body, {
            delimiters: [
                { left: "$$", right: "$$", display: true },
                { left: "$", right: "$", display: false },
                { left: "\\(", right: "\\)", display: false },
                { left: "\\[", right: "\\]", display: true }
            ],
            ignoredClasses: ["gist"]
        });})
</script>
    
</article>

    

    

     
    
        
    

    <footer class="site-footer">
    <section class="copyright">
        &copy; 
        
            2022 - 
        
        2024 ydsungan 的博客
    </section>
    
    <section class="powerby">
        Built with <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> <br />
        Theme <b><a href="https://github.com/CaiJimmy/hugo-theme-stack" target="_blank" rel="noopener" data-version="3.27.0">Stack</a></b> designed by <a href="https://jimmycai.com" target="_blank" rel="noopener">Jimmy</a>
    </section>
</footer>


    
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    
    <div class="pswp__bg"></div>

    
    <div class="pswp__scroll-wrap">

        
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                
                
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div><script 
                src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"integrity="sha256-ePwmChbbvXbsO02lbM3HoHbSHTHFAeChekF1xKJdleo="crossorigin="anonymous"
                defer
                >
            </script><script 
                src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"integrity="sha256-UKkzOn/w1mBxRmLLGrSeyB4e1xbrp4xylgAWb3M42pU="crossorigin="anonymous"
                defer
                >
            </script><link 
                rel="stylesheet" 
                href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css"crossorigin="anonymous"
            ><link 
                rel="stylesheet" 
                href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css"crossorigin="anonymous"
            >

            </main>
        </div>
        <script 
                src="https://cdn.jsdelivr.net/npm/node-vibrant@3.1.6/dist/vibrant.min.js"integrity="sha256-awcR2jno4kI5X0zL8ex0vi2z&#43;KMkF24hUW8WePSA9HM="crossorigin="anonymous"
                
                >
            </script><script type="text/javascript" src="/ts/main.js" defer></script>
<script>
    (function () {
        const customFont = document.createElement('link');
        customFont.href = "https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap";

        customFont.type = "text/css";
        customFont.rel = "stylesheet";

        document.head.appendChild(customFont);
    }());
</script>

    </body>
</html>
